package com.itheima.controller;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.itheima.common.BaseContext;
import com.itheima.common.R;
import com.itheima.domain.User;
import com.itheima.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.coyote.http11.filters.BufferedInputFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.util.UUID;

/**
 * 图片文件的上传下载
 */
@Slf4j
@RestController
@RequestMapping("/common")
@Api(tags = "文件上传下载")
public class CommonController {
    @Value("${reggie.path}")
    private String imgFile;
    @Autowired
    private UserService service;

    /**
     * 文件上传方法
     * 获取文件上传的原始名，截取文件后缀
     * 生成随机文件名，拼接后缀
     * 获取目录路径
     * 判定目录路径是否存在
     * 不存在则创建目录路径
     * 通过file.transferTo(new File(imgFile + s));
     * 将文件存入指定位置
     *
     * @param file
     * @return
     */
    @ApiOperation(value = "图片上传")
    @ApiImplicitParam(name = "file", value = "接收图片文件", readOnly = true)
    @PostMapping("/upload")
    public R<String> upload(MultipartFile file) {
        //file是一个临时文件，需要转存到指定位置，否则本次请求完成后临时文件会删除
        log.info(file.toString());
        //获取上传的原始文件名
        String files = file.getOriginalFilename().toString();
        String substringFile = files.substring(files.lastIndexOf("."));
        //使用uuid重新生成不重复的id名
        String s = UUID.randomUUID().toString() + substringFile;
        //判定文件夹名是否存在
        //创建一个目录对象
        File imgFiles = new File(imgFile);
        if (!imgFiles.exists()) {
            imgFiles.mkdirs();
        }
        try {
            file.transferTo(new File(imgFile + s));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return R.success(s);
    }

    @ApiOperation(value = "用户头像上传")
    @ApiImplicitParam(name = "file", value = "接收用户头像", readOnly = true)
    @PostMapping("/upload/user")
    public R<String> uploadUser(MultipartFile file, HttpSession session) {
        //file是一个临时文件，需要转存到指定位置，否则本次请求完成后临时文件会删除
        log.info(file.toString());
        //获取上传的原始文件名
        String files = file.getOriginalFilename().toString();
        String substringFile = files.substring(files.lastIndexOf("."));
        //使用uuid重新生成不重复的id名
        String s = UUID.randomUUID().toString() + substringFile;
        //判定文件夹名是否存在
        //创建一个目录对象
        File imgFiles = new File(imgFile);
        if (!imgFiles.exists()) {
            imgFiles.mkdirs();
        }
        try {
            file.transferTo(new File(imgFile + s));
        } catch (IOException e) {
            e.printStackTrace();
        }
        User user = new User();
        user.setId((Long) session.getAttribute("user"));
        user.setAvatar(s);
        service.updateById(user);
        return R.success(s);
    }

    /**
     * 文件下载方法
     * 通过传输进来的文件名字加上指定路径创建字符缓冲输入流写入数据
     * 将数据写出到页面
     * 释放资源
     *
     * @param name
     * @param response
     */
    @ApiOperation(value = "图片下载")
    @ApiImplicitParam(name = "name", value = "图片名字", readOnly = true)
    @GetMapping("/download")
    public void download(String name, HttpServletResponse response) {
        log.info("文件名字:{}", name);
        //根据图片名字获取文件信息
        try {
            BufferedInputStream fileInputStream = new BufferedInputStream(new FileInputStream(imgFile + name));
            //输出流，通过输出流将文件写回浏览器
            log.info("图片名字为:{}", imgFile + name);
            ServletOutputStream outputStream = response.getOutputStream();
            //表名写到页面的是图片文件
            response.setContentType("image/jpeg");
//            int a;
//            byte[] bytes = new byte[1024];
//            while ((a = fileInputStream.read(bytes)) != -1) {
//                //将获取到的信息写入网页
//                outputStream.write(bytes, 0, a);
//                outputStream.flush();
//            }
//            //关闭资源
//            log.info("图片资源写入完成");
            //通过IO工具类复制信息
            IOUtils.copy(fileInputStream, outputStream);
            log.info("图片资源写入完成");
            outputStream.close();
            fileInputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
